/*
 * Copyright (C) 2008
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.sca4idea.facet;

import com.intellij.openapi.options.ConfigurationException;
import com.googlecode.sca4idea.SCABundle;
import com.googlecode.sca4idea.providers.SCAProvider;
import com.googlecode.sca4idea.providers.SCAProviderRegistry;
import org.jetbrains.annotations.Nls;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;
import java.util.*;
import java.util.List;

/**
 * Panel used for providing the user interface for configuring a facet.
 */
public class FacetEditorPanel {
    private final SCAFacetConfiguration configuration;
    private JPanel mainPanel;
    private JRadioButton useAllProvidersRadioButton;
    private JRadioButton useOnlySelectedProvidersRadioButton;
    private JPanel providerSelectionPanel;
    private Map<SCAProvider, JCheckBox> selectors;

    public FacetEditorPanel(SCAFacetConfiguration configuration) {
        this.configuration = configuration;

        // Attach the radio button listeners
        useAllProvidersRadioButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                updateManualSelectionPanel();
            }
        });
        useOnlySelectedProvidersRadioButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                updateManualSelectionPanel();
            }
        });

        // Populate the SCA providers
        selectors = new HashMap<SCAProvider, JCheckBox>();
        providerSelectionPanel.setLayout(new GridLayout(0, 1));
        SCAProvider[] providers = SCAProviderRegistry.getInstance().getAllProviders();
        for (SCAProvider provider : providers) {
            JCheckBox cb = new JCheckBox();
            cb.setName(provider.getId());
            cb.setText(provider.getDisplayName());
            providerSelectionPanel.add(cb);
            selectors.put(provider, cb);
        }
    }

    @Nls
    public String getDisplayName() {
        return SCABundle.message("service.component.architecture.title");
    }

    public boolean isModified() {
        if (useAllProvidersRadioButton.isSelected()) {
            // If use all is selected, then just see if the configuration wasn't specific
            return configuration.getSelectedProviders() != null;
        } else {
            if (configuration.getSelectedProviders() == null) return true;

            // We need to compare the lists
            Set<SCAProvider> providers = new HashSet<SCAProvider>(Arrays.asList(configuration.getSelectedProviders()));
            for (SCAProvider provider : SCAProviderRegistry.getInstance().getAllProviders()) {
                if (selectors.get(provider).isSelected()) {
                    if (!providers.remove(provider)) return true;
                }
            }

            return providers.size() != 0;
        }
    }

    public void apply() throws ConfigurationException {
        if (useAllProvidersRadioButton.isSelected()) {
            configuration.setSelectedProviders(null);
        } else {
            List<SCAProvider> providers = new ArrayList<SCAProvider>();
            for (SCAProvider provider : SCAProviderRegistry.getInstance().getAllProviders()) {
                if (selectors.get(provider).isSelected()) {
                    providers.add(provider);
                }
            }

            configuration.setSelectedProviders(providers.toArray(new SCAProvider[providers.size()]));
        }
    }

    public void reset() {
        // Configure the checkboxes
        useAllProvidersRadioButton.setSelected(configuration.getSelectedProviders() == null);
        useOnlySelectedProvidersRadioButton.setSelected(configuration.getSelectedProviders() != null);

        // Populate the list
        SCAProvider[] providers = configuration.getSelectedProviders();
        if (providers == null) providers = SCAProviderRegistry.getInstance().getAllProviders();
        Set<SCAProvider> providerSet = new HashSet<SCAProvider>(Arrays.asList(providers));

        for (SCAProvider provider : SCAProviderRegistry.getInstance().getAllProviders()) {
            selectors.get(provider).setSelected(providerSet.contains(provider) || provider.isAlwaysActive());
        }

        // Update the selection state
        updateManualSelectionPanel();
    }

    public void disposeUIResources() {
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    private void updateManualSelectionPanel() {
        for (SCAProvider provider : selectors.keySet()) {
            JCheckBox cb = selectors.get(provider);

            if (provider.isAlwaysActive()) {
                cb.setEnabled(false);
            } else {
                cb.setEnabled(useOnlySelectedProvidersRadioButton.isSelected());
            }
        }
    }
}
